<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2023/4/27
 * Time: 18:12
 */
//https://www.badianboke.com/PHP/208.html
//https://www.jianshu.com/p/f5e33215c13c
//https://blog.csdn.net/haibo0668/article/details/121606124
/**
 * $is_pushed = Queue::push($job_handler_classname, $job_data, "dismiss_job_queue"); 任务名也可以空
 *
 * --daemon 是否循环执行，如果不加该参数则该命令处理完下一个消息就退出。
--queue dismiss_job_queue 要处理的队列的名称
--delay 0 如果本次任务执行抛出异常且任务未被删除时，设置其下次执行前延迟多少秒，默认为0。
--force 系统处于维护状态时，是否仍然处理任务，并未找到相关说明。
--memory 128 该进程允许使用的内存上限，以M为单位。
--sleep 3 如果队列中无任务则sleep多少秒后重新检查(work+daemon模式)或退出(listen或非daemon模式)
--tries 2 如果任务已经超过尝试次数上限，则触发“任务尝试数超限”事件，默认为0。

 * Cache::get("think:queue:restart") 从缓存得到上次重启的事件
 *
 * 启动一个工作进程来处理消息队列
 * $ php think queue:work --queue dismiss_job_queue
 * /www/server/php/74/bin/php think queue:listen --queue Job_Cutimage
 *
 * --queue dismiss_job_queue 监听队列的名称
--delay 0 如果本次任务执行抛出异常且任务未被删除时，设置其下次执行前延迟多少秒，默认为0。
--memory 128 该进程允许使用的内存上限，以M为单位。
--sleep 3 如果队列中无任务，则多长时间后重新检查。
--tries 0 如果任务已经超过重发次数上限，则进入失败处理逻辑，默认为0。
--timeout 60 工作进程允许执行的最长时间，以秒为单位。
 *$ php think queue:listen --queue dismiss_job_queue
 *
 *
 * 执行原理不同
Work模式是单进程的处理模式，按照是否设置--daemon参数又可以分为单次执行和循环执行两种模式。单次执行不添加--daemon参数，该模式下Work进程在从处理完下一个消息后直接结束当前进程。当队列为空时会sleep一段时间然后退出。循环执行添加了--daemon参数，该模式下Work进程会循环地处理队列中的消息直到内存超出参数配置才结束进程。当队列为空时会在每次循环中sleep一段时间。

Listen命令是“双进程+管道”的处理模式，Listen命令所在的进程会循环地创建单次执行模式的Work进程，每次创建的Work进程只消费一个消息就会结束，然后Listen进程再创建一个新的Work进程。Listen进程会定时检查当前的Work进程执行时间是否超过了--timeout参数的值，如果已经超过则Listen进程会杀掉所有Work进程，然后抛出异常。Listen进程会通过管道来监听当前的Work进程的输出，当Work进程有输出时Listen进程会将输出写入到stdout/stderr。Listen进程会定时通过proc_get_status()函数来监控当前的Work进程是否仍再运行，Work进程消费完一个任务之后，Work进程就结束了，其状态会变成terminated，此时Listen进程就会重新创建一个新的Work进程并对其计时，新的Work进程开始消费下一个任务。
注意当代码有更新时Work模式下需要手动去执行php think queue:restart命令重启队列来使改动生效，而Listen模式会自动生效无需其它操作。
 *
 *
 * 延迟执行的使用方式

在生产者业务代码中
// 即时执行
$is_pushed = Queue::push($job_handler_classname, $job_data, $job_queue_name)

// 延迟2秒执行
$is_pushed = Queue::later(2, $job_handler_classname, $job_data_arr, $job_queue_name);

// 延迟到2019-06-01 00:00:00时刻执行
$time2wait = strtotime("2019-06-01 00:00:00") - strtotime("now");
$is_pushed = Queue::later($time2wait, $job_handler_classname, $job_data_arr, $job_queue_name);
 *
在消费者类中
// 重发，即时执行
$job->release();

// 重发，延迟2秒后执行
$job->release(2);

// 延迟到2019-06-01 00:00:00时刻执行
$time2wait = strtotime("2019-06-01 00:00:00") - strtotime("now");
$job->release($time2wait);


php think queue:listen //监听 开发环境用
php think queue:work //只执行一次
nohup php think queue:work --daemon //守护进程，多次执行
 *
 * 指定队列 badianQueue
php think queue:listen --queue badianbokeSendMsg//监听 开发环境用
php think queue:work  --queue badianbokeSendMsg//只执行一次
nohup php think queue:work  --queue badianbokeSendMsg --daemon //守护进程，多次执行
 *
 * 停止命令：
 * php think queue:restart
 *
 *如果一个任务类里有多个小任务的话，如上面的例子二，需要用@+方法名app\lib\job\Job2@task1、app\lib\job\Job2@task2
 * 对应类的里面方法就不在是fire()  而是改为task1()  task2();
 */
return [
    //'connector' => 'Sync'
    'connector' => 'redis',         // 队列驱动使用 redis 推荐， 可选 database
    'expire'=>null,              //多久被重复执行 可禁止
    'host' => '127.0.0.1',          // redis 主机地址
    'password' => '',             // redis 密码
    'port' => 6379,                     // redis 端口
    'select' => 0,                   // redis db 库, 建议显示指定 1-15 的数字均可，如果缓存驱动是 redis，避免和缓存驱动 select 冲突
    'timeout' => 0,                     // redis 超时时间
    'persistent' => false,              // redis 持续性，连接复用
];